﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using GalaSoft.MvvmLight.Command;
using MetroLog;
using MishraReader.Services;
using MishraReader.ViewModels.AppServices;
using MishraReader.ViewModels.Base;


namespace MishraReader.ViewModels
{
    public interface ISignInViewModel : IDialogViewModel
    {
    }

    public class SignInViewModel : DialogViewModelBase, ISignInViewModel
    {
        private static readonly ILogger Log = LogManagerFactory.DefaultLogManager.GetLogger<SignInViewModel>();
        private readonly IWpfApplication _application;
        private readonly ICredentialProvider _credentialProvider;
        private readonly ILightWeakEventManager _eventManager;
        private readonly IGoogleReaderService _gService;
        private string _errorMessage;
        private string _password;
        private bool _rememberMe;
        private string _username;

        public SignInViewModel(ICredentialProvider credentialProvider,
                               ILightWeakEventManager eventManager,
                               IGoogleReaderService gService,
                               IWpfApplication application)
        {
            _credentialProvider = credentialProvider;
            _eventManager = eventManager;
            _gService = gService;
            _application = application;

            ConnectCommand = new RelayCommand(Connect, CanConnectExecute);
        }

        public ICommand ConnectCommand { get; private set; }

        public string ErrorMessage
        {
            get { return _errorMessage; }
            private set { Set(ref _errorMessage, value); }
        }

        public string Password
        {
            get { return _password; }
            set { Set(ref _password, value); }
        }

        public bool RememberMe
        {
            get { return _rememberMe; }
            set { Set(ref _rememberMe, value); }
        }

        public string Username
        {
            get { return _username; }
            set { Set(ref _username, value); }
        }

        protected override void OnCancelExecuted()
        {
            base.OnCancelExecuted();

            _application.Shutdown();
        }

        private bool CanConnectExecute()
        {
            return !string.IsNullOrWhiteSpace(Username) && !string.IsNullOrWhiteSpace(Password);
        }

        private async void Connect(string userName, string password)
        {
            // Clear previous error message
            ErrorMessage = null;

            // Validation
            if (string.IsNullOrWhiteSpace(userName) || string.IsNullOrWhiteSpace(password))
            {
                ErrorMessage = Strings.SignInValidationError;
                return;
            }

            try
            {
                IsBusy = true;

                await _gService.Connector.Connect(userName, password);

                if (RememberMe)
                {
                    _credentialProvider.Login = userName;
                    _credentialProvider.Password = password;
                    await _credentialProvider.Persist();
                }
                else
                {
                    _credentialProvider.Login = null;
                    _credentialProvider.Password = null;
                    await _credentialProvider.Persist();
                }

                ExecuteOkayCommand();

                _eventManager.Send(ApplicationMessages.Connected);
            }
            catch (Exception e)
            {
                ErrorMessage = "Unable to connect";

                Log.Error("Connect", e);
                // _errorService.HandleException(e);
            }
            finally
            {
                IsBusy = false;
            }
        }

        private void Connect()
        {
            if (CanConnectExecute())
            {
                Connect(Username, Password);
            }
        }
    }
}